package com.pi.nbcenter.device.controller.iot;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.pi.base.dto.result.AppResult;
import com.pi.base.dto.result.ServiceResult;
import com.pi.base.util.http.RequestUtil;
import com.pi.base.util.lang.ByteUtil;
import com.pi.base.util.lang.StringUtil;
import com.pi.iot.repository.constants.PiInsEnum;
import com.pi.iot.repository.huawei.bean.notify.HuaWeiIotRecord;
import com.pi.nbcenter.base.task.handler.HuaWeiIotRecordTask;
import com.pi.nbcenter.device.bean.dto.ins.base.InsParam;
import com.pi.nbcenter.device.bean.dto.nb.IotDeviceInfoDTO;
import com.pi.nbcenter.device.service.partner.BasePartnerSubscriptionService;
import com.pi.nbcenter.device.service.pi.external.PiGlobalDeviceService;
import com.pi.nbcenter.device.service.pi.external.PiInsService;
import com.pi.nbcenter.device.service.pi.internal.PiIotDevService;

@RequestMapping("/device")
@RestController
public class IotDeviceController {
  private static final Logger logger = LoggerFactory.getLogger(IotDeviceController.class);
  @Autowired
  private PiIotDevService iotDevService;
  @Autowired
  private PiGlobalDeviceService commonDeviceService;
  @Autowired
  private BasePartnerSubscriptionService subscriptionService;
  @Autowired
  private HuaWeiIotRecordTask huaWeiIotRecordTask;
  @Autowired
  private PiInsService piInsService;
  
  /**
   * @description 注册设备
   * @param imei
   * @return
   * @throws Exception 
   */
  @PostMapping("/regdevice")
  public AppResult registerDevice(@RequestParam(required=false) String imei,
      @RequestParam(required=false) Long partnerCode,
      @RequestParam(required=false) Long sourceId,
      @RequestParam(required=false) String nbDevId) throws Exception{
    if(null == partnerCode){
      partnerCode = sourceId;
    }
    logger.info("注册：IMEI:{}, 合作商编号：{}, 设备编号：{}", imei, partnerCode, nbDevId);
    return commonDeviceService.registerDevice(imei, partnerCode, nbDevId);
  }
  
  /**
   * @description 注册设备
   * @param imei
   * @return
   * @throws Exception 
   */
  @PostMapping("/delete")
  public AppResult remove(@RequestParam(required=false) String imei,
      @RequestParam(required=false) Long sourceId) throws Exception{
    logger.info("注销设备：IMEI:{}, 合作商编号：{}", imei, sourceId);
    return commonDeviceService.deleteDevice(imei, sourceId);
  }
  
  /**
   * @description 注册设备
   * @param imei
   * @return
   */
  @PostMapping("/queryDeviceStatus")
  public AppResult queryDeviceStatus(@RequestParam(required=false) String imei){
    AppResult result;
    logger.info("查询状态：IMEI:{}", imei);
    if(StringUtils.isEmpty(imei)){
      result = AppResult.newFailResult("设备imei号为空");
    }else{
      result = AppResult.newSuccessResult(commonDeviceService.queryDeviceStatus(imei));
    }
    return result;
  }
  
  /**
   * @description 注册设备
   * @param imei
   * @return
   * @throws Exception 
   */
  @PostMapping("/remoteOpenLock")
  public AppResult remoteOpenLock(String imei)
      throws Exception{
    logger.info("远程开门-IMEI:{}", imei);
    AppResult result = commonDeviceService.remoteOpenLock(imei);
    logger.info("远程开门指令结果： {}", result.toString());
    return result;
  }
  
  /**
   * @description 注册设备
   * @param imei
   * @return
   * @throws Exception 
   */
  @PostMapping("/queryDeviceInfo")
  public AppResult queryDeviceInfo(@RequestParam(required=false) String imei)
      throws Exception{
    logger.info("查询平台设备信息-IMEI:{}", imei);
    IotDeviceInfoDTO info = iotDevService.queryPlatDeviceInfoByImei(imei);
    return AppResult.newSuccessResult(info);
  }
  
  /**
   * @description 通知回调 https://121.40.178.129:4437/nbcenter/device/callback
   */
  @PostMapping("/callback")
  public String notification(HttpServletRequest request){
    String randomTag = StringUtil.generateNonce(5);
//    logger.info("[{}]接收到回调通知：{}", randomTag, request.getParameterMap());
    try {
//        String json = "{\"notifyType\":\"deviceDataChanged\",\"deviceId\":\"f514aa2a-b848-4e8d-906d-2b7da67b4b28\",\"gatewayId\":\"f514aa2a-b848-4e8d-906d-2b7da67b4b28\",\"requestId\":null,\"service\":{\"serviceId\":\"Connectivity\",\"serviceType\":\"Connectivity\",\"data\":{\"signalStrength\":-714,\"linkQuality\":-133,\"signalECL\":1,\"cellId\":78751515,\"signalPCI\":199,\"signalSNR\":14,\"mode\":2},\"eventTime\":\"20180602T062810Z\"}}";//RequestUtil.getJSONData(request);
        String data = RequestUtil.getJSONData(request);
        if(StringUtils.isNotEmpty(data)){
          HuaWeiIotRecord iotRecord = JSON.parseObject(data, HuaWeiIotRecord.class);
          if(null != iotRecord && null != iotRecord.getDeviceId()){
            if("e6e11fbc-ee93-46d1-bf03-5c17810ba247".equalsIgnoreCase(iotRecord.getDeviceId())){
              sendInsToDessmann();
            }
            //更新设备的状态为在线
            huaWeiIotRecordTask.process(iotRecord);
          }
        }
        logger.info("[{}]接收到body数据： {}", randomTag, data);
    } catch (IOException e) {
      logger.error("",e);
    }
    return "success";
  }
  
  @PostMapping("/subscribe")
  public AppResult subscribe(@RequestParam(required=false) Long partnerCode,
      @RequestParam(required=false) Long sourceId,
      @RequestParam(required=false) String remoteUri, 
      @RequestParam(required=false) Integer notifyType){
    if(null == partnerCode){
      partnerCode = sourceId;
    }
    subscriptionService.addPartnerSubscription(partnerCode, notifyType, remoteUri);
    return AppResult.newSuccessResult("订阅成功", null);
  }
  
  @PostMapping("/unsubscribe")
  public AppResult unsubscribe(@RequestParam(required=false) Long partnerCode,
      @RequestParam(required=false) Long sourceId,
      @RequestParam(required=false) String remoteUri){
    if(null == partnerCode){
      partnerCode = sourceId;
    }
    subscriptionService.deletePartnerSubscription(partnerCode, remoteUri);
    return AppResult.newSuccessResult("取消订阅成功", null);
  }
  
  @PostMapping("/upgrade")
  public AppResult upgradeOldversionedDevice(Integer version, Long partnerCode, String imeis) 
      throws Exception{
    commonDeviceService.upgradeOldversionedDevice(partnerCode, version, StringUtils.isNotEmpty(imeis)? Arrays.asList(imeis.split(",")): null);
    return AppResult.OK;
  }
  
  @PostMapping("/degrade")
  public AppResult degradeDevice(Long partnerCode, String devIdList, Integer version) 
      throws Exception{
    boolean succeed = iotDevService.degradeDevice(partnerCode, devIdList, version);
    if(succeed){      
      return AppResult.OK;
    }else{
      return AppResult.newFailResult("DEV_INFO.DEV_DEGRADE_FAILED");
    }
  }
  
  public AppResult clearLockUserInfo(String imei, Long sourceId) throws Exception {
    InsParam insParam = new InsParam();
    insParam.setImei(imei);
    insParam.setInsEnum(PiInsEnum.LOCK_RESET);
    insParam.setSourceId(sourceId);
    ServiceResult<String> result = piInsService.sendIns(insParam);
    if(result.equalSuccess())
      return AppResult.OK;
    return AppResult.newFailResult(result.getMsg(), result.getErrorCode());
  }
  
  private void sendInsToDessmann() throws UnknownHostException, IOException{
    String ins = "FE 02 04 00 21 0B DC 7B CB 40 B6 6B 00 00 00 00 00 00 00 00 00 00 00 00 01 DE 02 00 00 00 00 00 18 05 09 17 58 00 05 2B";
    Socket socket = new Socket("118.190.98.192", 8898);
    OutputStream out = socket.getOutputStream();
    out.write(ByteUtil.hexToByte(ins));
    out.flush();
    out.close();
    socket.close();
  }
}
